#include "dct.h"
#include "my_types.h"

void dct1_init() {}

const D_CONST FA1(0.707106781f); 
const D_CONST FA2 (0.541196100f); 
const D_CONST FA3 (FA1);
const D_CONST FA4 (1.306562965f); 
const D_CONST FA5 (0.382683433f); 

void fdct_1d(D_DCT row[8], D_DCT row_res[8], D_BIAS bias) {
  D_DCT x0, x1, x2, x3, t0, t1, t2, t3, t4, t5, t6, t7;

  t0 = (D_DCT13) (row[0] + row[7] - bias);
  t7 = (D_DCT13) (row[0] - row[7]);
  t1 = (D_DCT13) (row[1] + row[6] - bias);
  t6 = (D_DCT13) (row[1] - row[6]);
  t2 = (D_DCT13) (row[2] + row[5] - bias);
  t5 = (D_DCT13) (row[2] - row[5]);
  t3 = (D_DCT13) (row[3] + row[4] - bias);
  t4 = (D_DCT13) (row[3] - row[4]);
  
  /* even part */
  x0 = t0 + t3;
  x2 = t1 + t2;
  row_res[0] = (D_DCT) (x0 + x2);
  row_res[4] = (D_DCT) (x0 - x2);
  
  x1 = t0 - t3;
  x3 = t1 - t2;
  t0 = (x1 + x3) * FA1;
  row_res[2] = (D_DCT) (x1 + t0);
  row_res[6] = (D_DCT) (x1 - t0);
  
  /* odd part */
  x0 = t4 + t5;
  x1 = t5 + t6;
  x2 = t6 + t7;
  
  t3 = x1 * FA1;
  t4 = t7 - t3;
  
  t0 = (x0 - x2) * FA5;
  t1 = x0 * FA2 + t0;
  row_res[3] = (D_DCT) (t4 - t1);
  row_res[5] = (D_DCT) (t4 + t1);
  
  t7 += t3;
  t2 = x2 * FA4 + t0;
  row_res[1] = (D_DCT) (t7 + t2);
  row_res[7] = (D_DCT) (t7 - t2);
}

void dct1_run(fifo<D_PIXEL> *IN1, fifo<D_DCT> *IN2, fifo<D_DCT> *OUT1, fifo<D_DCT> *OUT2, D_BIAS bias) {
  int i,j;
  short tmp[64];
  D_DCT row[8], row_res[8]; 

 if (bias==256) {
  while (IN1->len() >= 64) {

    for (i = 0; i<8; ++i) {
      for (j = 0; j<8; ++j)
	row[j] = IN1->read();
      
      fdct_1d(row, row_res,  bias);
    
      for (j = 0; j<8; ++j) {
	OUT1->write(row_res[j]);
      }
    }
  }
 }
 else {
  while (IN2->len() >= 64) {

    for (i = 0; i<8; ++i) {
      for (j = 0; j<8; ++j)
	row[j] = IN2->read();
      
      fdct_1d(row, row_res,  bias);
    
      for (j = 0; j<8; ++j) {
	OUT2->write(row_res[j]);
      }
    }
  }
 }
}
